#include "DataStorageCM.h"
#include <EEPROM.h>
#include "log.h"

DataStorageCM::DataStorageCM(Mail<>& mb,I2CSlave& i2c_slave):_mb(mb),_i2c_slave(i2c_slave)
{

}

bool DataStorageCM::load()
{
    if(this->read_data_storage_eof() != DATA_STORAGE_EOF){
        return false;
    }
    for(uint32_t i=0;i<data_storage_header_size();i++){
        module_header_reg().data[i] = EEPROM.read(i);
    }
    
    //载入模组通用信息
    for(uint32_t i=(DATA_STORAGE_HEADER_REG_SIZE);i<(DATA_STORAGE_GENERAL_REG_SIZE+DATA_STORAGE_HEADER_REG_SIZE);i++){
        module_reg().module_general_reg.data[i-DATA_STORAGE_HEADER_REG_SIZE] = EEPROM.read(i);
    }
    return true;

}
int DataStorageCM::read_data_storage_eof()
{
    int eof_address= DATA_STORAGE_STATUS_EOF_ADDRESS;
    _data_storage_eof._AA = EEPROM.read(eof_address);
    _data_storage_eof._55 = EEPROM.read(eof_address+1);
    return _data_storage_eof.value;
}

void DataStorageCM::make_default()
{
     //生成头部信息
    module_header_reg().module_number.value      = 0x0004;
    module_header_reg().hardware_version         = 0x01;
    module_header_reg().software_version         = 0x01;
    module_header_reg().module_type              = 1;
    module_header_reg().protocol_part_1.value    = 0x87;
    module_header_reg().protocol_part_2.value    = 0x01;
    strcpy((char*)& module_header_reg().module_name[0],"WF1-Current_Monitor");
    
    //写入头部信息到EEPROM
    for(uint8_t i=0;i<data_storage_header_size();i++){
        EEPROM.write(i, module_header_reg().data[i]); 
    }

    module_general_reg_t& module_general_reg = DataStorageCM::module_reg().module_general_reg;
    //生成寄存器默认配置
    module_general_reg.master_update_reg.value                        = 0;
    module_general_reg.slave_interrupt_reg.value                      = 0;
    module_general_reg.slave_update_reg.value                         = 0;
    module_general_reg.current_sample_channel_enable_reg.value        = 0;
    module_general_reg.current_sample_threshold_alarm_enable_reg.value= 0;
    //设置默认配置
    for(uint32_t i=0;i<4;i++){
        module_general_reg.module_general_channel[i].slave_current_sample_value_reg.value     = 0;
        module_general_reg.module_general_channel[i].slave_current_sample_threshold_reg.value  = 1023;
    }
    //写入默认配置到EEPROM
    for(uint8_t i=(DATA_STORAGE_HEADER_REG_SIZE);i<(DATA_STORAGE_HEADER_REG_SIZE+DATA_STORAGE_GENERAL_REG_SIZE);i++){
        EEPROM.write(i, module_general_reg.data[i-DATA_STORAGE_HEADER_REG_SIZE]);
    }
    //写入0x55AA激活配置
    EEPROM.write(DATA_STORAGE_STATUS_EOF_ADDRESS,0xAA);
    EEPROM.write(DATA_STORAGE_STATUS_EOF_ADDRESS+1,0x55);
}

void DataStorageCM::check_update()
{
    bool _update = false;

    for(uint32_t i=0;i<data_storage_header_size();i++){
        if(!_mb.empty()){
            return;
        }
        if(EEPROM.read(i) !=  module_header_reg().data[i]){
            _update = true;
            break;
        }
    }

    if(_update){
        for(uint32_t i=0;i<data_storage_header_size();i++){
            if(!_mb.empty()){
                return;
            }
            EEPROM.write(i, module_header_reg().data[i]);
        }
        //log::debug("update eeprom header:%s\r\n",_update?"Y":"N");
    }

    _update = false;
    
    for(uint32_t _check_index=DATA_STORAGE_HEADER_REG_SIZE;_check_index<(DATA_STORAGE_HEADER_REG_SIZE+DATA_STORAGE_GENERAL_REG_SIZE);_check_index++){
        if(!_mb.empty()){
            return;
        }
        module_general_reg_t& module_general_reg = DataStorageCM::module_reg().module_general_reg;
        if(EEPROM.read(_check_index) !=  module_general_reg.data[_check_index-DATA_STORAGE_HEADER_REG_SIZE]){
            _update = true;
            break;
        }
    }

    if(_update){
    //写入默认配置到EEPROM
        module_general_reg_t& module_general_reg = DataStorageCM::module_reg().module_general_reg;
        for(uint8_t i=(DATA_STORAGE_HEADER_REG_SIZE);i<(DATA_STORAGE_HEADER_REG_SIZE+DATA_STORAGE_GENERAL_REG_SIZE);i++){
            if(!_mb.empty()){
                return;
            }
            EEPROM.write(i,module_general_reg.data[i-DATA_STORAGE_HEADER_REG_SIZE]);
        }
        //log::debug("update eeprom reg:%s\r\n",_update?"Y":"N");
    }

}

data_storage_reg_read_t& DataStorageCM::get_reg_data(uint8_t reg_address)
{
    switch (reg_address)
    {
        case 0x00:
        case 0x01:
        {
            _reg_read.data    =  module_header_reg().module_number.data;
            _reg_read.size    = sizeof( module_header_reg().module_number.data);
        }
        break;
        case 0x02:
        {
            _reg_read.data    =  module_header_reg().hardware_version_data;
            _reg_read.size    = sizeof( module_header_reg().hardware_version_data);
        }
        break;
        case 0x03:
        {
            _reg_read.data    =  module_header_reg().software_version_data;
            _reg_read.size    = sizeof( module_header_reg().software_version_data);
        }
        break;
        case 0x04:
        {
            _reg_read.data    =  module_header_reg().module_type_data;
            _reg_read.size    = sizeof( module_header_reg().module_type_data);
        }
        break;
        case 0x05:
        case 0x06:
        {
            _reg_read.data    =  module_header_reg().protocol_data;
            _reg_read.size    = sizeof( module_header_reg().protocol_data);
        }
        break;
        case 0x07:
        {
            _reg_read.data    =  module_header_reg().module_name;
            _reg_read.size    = sizeof( module_header_reg().module_name);
        }
        break;
        //case 0x40://只写
        case 0x41:
        {
            _reg_read.data    =          module_reg().module_general_reg.slave_interrupt_reg.data;
            _reg_read.size    = sizeof( module_reg().module_general_reg.slave_interrupt_reg.data);
        }
        break;
        //case 0x42://只写
        case 0x43:
        {
            _reg_read.data    =          module_reg().module_general_reg.current_sample_channel_enable_reg.data;
            _reg_read.size    = sizeof( module_reg().module_general_reg.current_sample_channel_enable_reg.data);
        }
        break;
    case 0x44:
        {
            _reg_read.data    =          module_reg().module_general_reg.current_sample_threshold_alarm_enable_reg.data;
            _reg_read.size    = sizeof( module_reg().module_general_reg.current_sample_threshold_alarm_enable_reg.data);
        }
        break;
    // case 0x45:break;
    // case 0x46:break;
    // case 0x47:break;
    case 0x48:
    case 0x49:// A0-threshold
    {
        _reg_read.data    =          module_reg().module_general_reg.module_general_channel[0].slave_current_sample_threshold_reg.data;
        _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[0].slave_current_sample_threshold_reg.data);
    }
    break;
    case 0x4A:
    case 0x4B:// A1-threshold
    {
        _reg_read.data    =          module_reg().module_general_reg.module_general_channel[1].slave_current_sample_threshold_reg.data;
        _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[1].slave_current_sample_threshold_reg.data);
    }
    break;
    case 0x4C:
    case 0x4D:// A2-threshold
    {
        _reg_read.data    =          module_reg().module_general_reg.module_general_channel[2].slave_current_sample_threshold_reg.data;
        _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[2].slave_current_sample_threshold_reg.data);
    }
    break;
    case 0x4E:
    case 0x4F:// A3-threshold
    {
        _reg_read.data    =          module_reg().module_general_reg.module_general_channel[3].slave_current_sample_threshold_reg.data;
        _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[3].slave_current_sample_threshold_reg.data);
    }
    break;

    // case 0x50:
    // case 0x51:// A0-I
    // {
    //     _reg_read.data    =          module_reg().module_general_reg.module_general_channel[0].slave_current_sample_value_reg.data;
    //     _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[0].slave_current_sample_value_reg.data);
    // }
    // break;
    // case 0x52:
    // case 0x53:// A1-I
    // {
    //     _reg_read.data    =          module_reg().module_general_reg.module_general_channel[1].slave_current_sample_value_reg.data;
    //     _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[1].slave_current_sample_value_reg.data);
    // }
    // break;
    // case 0x54:
    // case 0x55:// A2-I
    // {
    //     _reg_read.data    =          module_reg().module_general_reg.module_general_channel[2].slave_current_sample_value_reg.data;
    //     _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[2].slave_current_sample_value_reg.data);
    // }
    // break;
    // case 0x56:
    // case 0x57:// A3-I
    // {
    //     _reg_read.data    =          module_reg().module_general_reg.module_general_channel[3].slave_current_sample_value_reg.data;
    //     _reg_read.size    = sizeof( module_reg().module_general_reg.module_general_channel[3].slave_current_sample_value_reg.data);
    // }
    // break;
    default:
    {
        _reg_read.data = (uint8_t*)"NG";
        _reg_read.size = 2;
    }
    break;
    }
    return _reg_read;
}

void DataStorageCM::schedule()
{
    if(!_i2c_slave.read(_master_data_read)){
        return;
    }
   this->update();
}
void DataStorageCM::update()
{
    module_general_reg_t& general_reg = DataStorageCM::module_reg().module_general_reg;
    log::debug("mem:%x:%x:%x-%x:%x:%x\r\n",
                _master_data_read.memory.data[0],
                _master_data_read.memory.data[1],
                _master_data_read.memory.data[2],
                _master_data_read.memory.data[3],
                _master_data_read.memory.data[4],
                _master_data_read.memory.data[5]);
    switch(_master_data_read.memory.data[0]){
        case 0x40:
        {
            // 更新数据A0-A3
            // general_reg.master_update_reg.value = _master_data_read.memory.data[1];
            // if(general_reg.master_update_reg.a0==1){

            // }
            // if(general_reg.master_update_reg.a1==1){

            // }
            // if(general_reg.master_update_reg.a2==1){

            // }
            // if(general_reg.master_update_reg.a3==1){

            // }
        }
        break;
        case 0x41://只读
        break;
        case 0x42://更新设置
        {   

        }
        break;
        case 0x43://CM(A0-A3)使能/s禁止
        {
            general_reg.current_sample_channel_enable_reg.value = _master_data_read.memory.data[1];
        }
        break;
        case 0x44://CM(A0-A3)阈值报警使能/禁止
        {
            general_reg.current_sample_threshold_alarm_enable_reg.value = _master_data_read.memory.data[1];
        }
        break;
        case 0x45://保留
        break;
        case 0x46://保留
        break;
        case 0x47://保留
        break;
        case 0x48://CM-A0电流采样阈值
        case 0x49://A0-threshold
        {
            general_reg.module_general_channel[0].slave_current_sample_threshold_reg.data[0] = _master_data_read.memory.data[1];
            general_reg.module_general_channel[0].slave_current_sample_threshold_reg.data[1] = _master_data_read.memory.data[2];
        }
        break;
        case 0x4A://CM-A1电流采样阈值
        case 0x4B://A1-threshold
        {
            general_reg.module_general_channel[1].slave_current_sample_threshold_reg.data[0] = _master_data_read.memory.data[1];
            general_reg.module_general_channel[1].slave_current_sample_threshold_reg.data[1] = _master_data_read.memory.data[2];
        }
        break;
        case 0x4C://CM-A2电流采样阈值
        case 0x4D://A2-threshold
        {
            general_reg.module_general_channel[2].slave_current_sample_threshold_reg.data[0] = _master_data_read.memory.data[1];
            general_reg.module_general_channel[2].slave_current_sample_threshold_reg.data[1] = _master_data_read.memory.data[2];
        }
        break;
        case 0x4E://CM-A3电流采样阈值
        case 0x4F://A3-threshold
        {
            general_reg.module_general_channel[3].slave_current_sample_threshold_reg.data[0] = _master_data_read.memory.data[1];
            general_reg.module_general_channel[3].slave_current_sample_threshold_reg.data[1] = _master_data_read.memory.data[2];
            log::debug("4e-4f->write:%d\r\n",general_reg.module_general_channel[3].slave_current_sample_threshold_reg.value);
        }
        break;
        case 0x50:// CM-A0电流采样值
        case 0x51://A0-I-只读
        break;
        case 0x52:// CM-A1电流采样值
        case 0x53://A0-I-只读
        break;
        case 0x54:// CM-A2电流采样值
        case 0x55://A0-I-只读
        break;
        case 0x56:// CM-A3电流采样值
        case 0x57://A0-I-只读
        break;
        default:
        break;
    }
}
void DataStorageCM::cleanup()
{

}

